﻿using RBACDemo.Domain.Shared;
using RBACDemo.Domain.UserInfo;
using Youshow.Ace.Domain.Repository;
using Youshow.Ace.Domain.Services;

namespace RBACDemo.Domain.Managers;

public class RoleAuthManager(
    IRepository<ApiAuth> apiAuthRepository,
    IRepository<RoleApiAuthMapping> roleApiAuthMappingRepository) : DomainServicer
{
    /// <summary>
    ///  根据项目中的Service和Controller信息去对ApiAuth表中的数据进行CUD
    /// </summary>
    /// <param name="apiAuths">项目中的Service和Controller信息</param>
    public async Task AddApiAuthAsync(List<ApiAuth> apiAuths)
    {
        var willUpdateData = new List<ApiAuth>();
        var willDeleteData = new List<ApiAuth>();
        // 1.获取所有的ApiAuth
        var resApiAuth = await apiAuthRepository.GetListAsync();
        // 2.检测已有的数据并检测需要删除的数据
        resApiAuth.ForEach(m =>
        {
            // 通过返回值判定当前的ApiAuth是否需要删除
            var isUpdate = m.CheckAndUpdate(apiAuths);
            if (isUpdate == ApiAuthUpdateState.Delete)
            {
                willDeleteData.Add(m);
            }
            else if (isUpdate == ApiAuthUpdateState.Update)
            {
                willUpdateData.Add(m);
            }
        });

        // 3.筛选出需要添加的数据
        var resRoutePaths = resApiAuth.Select(m => m.RoutePath + "_" + m.Method);
        var willAddApiAuth = apiAuths.Where(m => !resRoutePaths.Contains(m.RoutePath + "_" + m.Method));
        // 4.实际操作
        await apiAuthRepository.UpdateManyAsync(willUpdateData);
        await apiAuthRepository.DeleteManyAsync(willDeleteData);
        await apiAuthRepository.InsertManyAsync(willAddApiAuth, false);
    }

    /// <summary>
    ///  获取角色信息的同时获取其权限信息
    /// </summary>
    /// <param name="roles">角色集合</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public async Task<List<Role>> GetApiAuthToRoleAsync(params Role[] roles)
    {
        if (roles != null && roles.Length > 0)
        {
            var resRoles = await apiAuthRepository.WithJoinAsync<RoleApiAuthMapping, Role>(
                roles.ToList(),
                m => m.ApiAuths);
            return resRoles;
        }

        throw new ArgumentNullException("roles");
    }

    /// <summary>
    ///  根据roleId去删除RoleApiAuthMapping表中的数据
    /// </summary>
    /// <param name="roleId">角色Id</param>
    public async Task DeleteRoleApiAuthAsync(long roleId)
    {
        await roleApiAuthMappingRepository.DeleteAsync(m => m.RoleId == roleId);
    }

    /// <summary>
    ///  roleId、apiAuthIds给角色添加相应的权限，保存在RoleApiAuthMapping表中
    /// </summary>
    /// <param name="roleId">角色Id</param>
    /// <param name="apiAuthIds">权限Id集合</param>
    public async Task AddRoleApiAuthAsync(long roleId, List<long> apiAuthIds)
    {
        List<RoleApiAuthMapping> roleApiAuthMappings = new();
        apiAuthIds.ForEach(m =>
        {
            roleApiAuthMappings.Add(new RoleApiAuthMapping()
            {
                RoleId = roleId,
                ApiAuthId = m
            });
        });
        await roleApiAuthMappingRepository.InsertManyAsync(roleApiAuthMappings, false);
    }
}